import { VRC6Channels, VRC6Mixer } from "./VRC6Mixer";

export class VRC6Sawtooth {

	private enable: boolean = false;

	private timer: number = 0;
	private timerMaxTemp: number = 0;
	private timerMax: number = 0;

	/**锯齿波第几步，总共7步，0-6 */
	private stepCount: number = 0;
	/**锯齿波音量升高程度 */
	private step: number = 0;
	/**上一次升高记录 */
	private lastStep: number = 0;
	private readonly mixer: VRC6Mixer;

	constructor(mixer: VRC6Mixer) {
		this.mixer = mixer;
	}

	WriteIO(address: number, value: number) {
		address &= 3;
		switch (address) {
			case 0:
				this.SetStep(value);
				break;
			case 1:
				this.SetTimerLow(value);
				break;
			case 2:
				this.SetTimerHighAndEnable(value);
				break;
		}
	}

	ClockRate() {
		if (!this.enable)
			return;

		if (this.timer === 0) {
			if (this.stepCount === 0) {
				this.lastStep = 0;
			} else {
				this.lastStep += this.step;
			}

			this.mixer.UpdateAmp(this.lastStep >> 3, VRC6Channels.Sawtooth);

			this.stepCount++
			this.stepCount %= 7;
			this.timer = this.timerMaxTemp;
		} else {
			this.timer--;
		}
	}

	private SetTimerLow(value: number) {
		this.timerMaxTemp = (this.timerMaxTemp & 0xF00) | value;
	}

	private SetTimerHighAndEnable(value: number) {
		this.timerMaxTemp = (this.timerMaxTemp & 0xFF) | ((value & 0xF) << 8);
		this.enable = (value & 0x80) !== 0;
		// this.enable = (value & 0x80) !== 0;
		if (!this.enable) {
			this.step = 0;
			this.stepCount = 0;
		}
	}

	private SetStep(value: number) {
		this.step = value & 0x3F;
	}
}